package com.lingjtx.common.pay.common;

import com.alibaba.fastjson2.JSONObject;
import com.lingjtx.common.core.RedisOptions;
import com.lingjtx.common.core.algorithm.AESUtil;
import com.lingjtx.common.core.constant.RedisConfig;
import com.lingjtx.common.core.util.StringUtil;
import com.lingjtx.common.pay.client.PaymentExecutor;
import com.lingjtx.common.pay.model.wx.Certificates;
import com.lingjtx.common.pay.model.wx.EncryptCertificate;
import com.lingjtx.common.pay.model.wx.WeixinPayCertConfig;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
public class DataCache {

    private final RedisOptions redis;
    private final PaymentExecutor executor;

    public DataCache(RedisOptions redis, PaymentExecutor executor) {
        this.redis = redis;
        this.executor = executor;
    }

    // 程序实现定期更新平台证书的逻辑，不要硬编码验证应答消息签名的平台证书。
    //定期调用该接口，间隔时间小于12 小时。
    //加密请求消息中的敏感信息时，使用最新的平台证书（即：证书启用时间较晚的证书）。
    //首次下载证书，可以使用微信支付提供的证书下载工具。
    //该接口没有query参数或者path参数，仅需要必要的头部信息，如签名认证信息等。
    //由于证书存在有效期的限制，微信支付会不定期地更换平台证书以确保交易安全，证书过期前会提前把新证书加入到平台证书下载列表中。
    // https://pay.weixin.qq.com/doc/v3/merchant/4012551764
    public WeixinPayCertConfig getCertificates() {
        WeixinPayCertConfig certConfig = (WeixinPayCertConfig) redis.get(RedisConfig.KEY_WEI_XIN_PAY_CERTIFICATES);
        if (certConfig == null || StringUtil.isEmpty(certConfig.getSerialNo())) {
            Certificates certList = executor.getCertificates();
            if (Objects.nonNull(certList) && StringUtil.isNotEmpty(certList.getData())) {
                EncryptCertificate certificate = certList.getData().getFirst().getEncrypt_certificate();

                String text = AESUtil.decryptToString(certificate.getCiphertext(),
                        executor.getProperties().getApiKey(),
                        certificate.getAssociated_data(),
                        certificate.getNonce());
                certConfig = new WeixinPayCertConfig();
                certConfig.setSerialNo(certList.getData().getFirst().getSerial_no());

                if (StringUtil.isNotEmpty(text)) {
                    String pem = text.replace("-----BEGIN CERTIFICATE-----","")
                            .replace("-----END CERTIFICATE-----","")
                            .replace("\n", "");
                    certConfig.setPemKey(pem);
                }
                redis.set(RedisConfig.KEY_WEI_XIN_PAY_CERTIFICATES, certConfig, RedisConfig.TIMEOUT_10_HOUR);
                return certConfig;
            }
        }
        return certConfig;
    }
}
